package com.huabo.session;

import com.huabo.serialize.Serializer;
import com.huabo.utils.CookieHelper;
import com.huabo.utils.KeyUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * Created by Jackie Liu on 2017/4/3.
 */
public class RedisSession implements UserSession{

    private static final Logger log = Logger.getLogger(RedisSession.class);

    private static final String LOGIN_TOKEN_COOKIE_NAME = "user_token";
    private static final String VERIFY_CODE_COOKIE_NAME = "vc_token";

    @Autowired
    private StringRedisTemplate redisTemplate;
    //序列化策略
    private Serializer serializer;
    //session有效时间，单位：分钟
    private int activeTime;

    @Override
    public boolean setSessionModel(HttpServletRequest request, HttpServletResponse response, SessionModel sessionModel) {
        try {
            final String value = serializer.getString(sessionModel);
            redisTemplate.opsForValue().set(sessionModel.getToken(), value, activeTime, TimeUnit.MINUTES);
            CookieHelper.setCookie(response, LOGIN_TOKEN_COOKIE_NAME, sessionModel.getToken());
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
        return true;
    }

    @Override
    public SessionModel getSessionModel(HttpServletRequest request) {
        try {
            String token = CookieHelper.getCookieValue(request, LOGIN_TOKEN_COOKIE_NAME);
            //System.out.println("token = " + token);
            if (StringUtils.isEmpty(token)) {
                return null;
            }
            String str = redisTemplate.opsForValue().get(token);
            if (StringUtils.isEmpty(str)) {
                return null;
            }
            SessionModel sessionModel = serializer.getObject(str, SessionModel.class);
            return sessionModel;
        } catch (Exception e) {
            log.error("", e);
            return null;
        }
    }

    @Override
    public boolean removeSession(HttpServletRequest request, HttpServletResponse response) {
        try {
            String token = CookieHelper.getCookieValue(request, LOGIN_TOKEN_COOKIE_NAME);
            if (StringUtils.isEmpty(token)) {
                return true;
            }
            CookieHelper.removeCookie(response, request, LOGIN_TOKEN_COOKIE_NAME, "");
            redisTemplate.delete(token);
            //cacheMaker.remove(token);
            return true;
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
    }

    @Override
    public void resetSessionTime(HttpServletRequest request) {
        String token = CookieHelper.getCookieValue(request, LOGIN_TOKEN_COOKIE_NAME);
        if (StringUtils.isEmpty(token)) {
            return;
        }
        String value = redisTemplate.opsForValue().get(token);
        redisTemplate.opsForValue().set(token, value, activeTime, TimeUnit.MINUTES);
    }

    @Override
    public void setVerifyCode(HttpServletRequest request, HttpServletResponse response, String verifyCode) {
        String token = KeyUtils.getKey();
        redisTemplate.opsForValue().set(token, verifyCode.toLowerCase(), 10, TimeUnit.MINUTES);
        CookieHelper.setCookie(response, VERIFY_CODE_COOKIE_NAME, token);
    }

    @Override
    public String getVerifyCode(HttpServletRequest request, HttpServletResponse response) {
        try {
            String token = CookieHelper.getCookieValue(request, VERIFY_CODE_COOKIE_NAME);
            //System.out.println("token = " + token);
            if (StringUtils.isEmpty(token)) {
                return null;
            }
            return redisTemplate.opsForValue().get(token);
        } catch (Exception e) {
            log.error("", e);
        }
        return null;
    }

    public Serializer getSerializer() {
        return serializer;
    }

    public void setSerializer(Serializer serializer) {
        this.serializer = serializer;
    }

    public int getActiveTime() {
        return activeTime;
    }

    public void setActiveTime(int activeTime) {
        this.activeTime = activeTime;
    }
}
